<template>
  <div
    v-if="!unmountOnClose || mergedVisible || mounted"
    v-show="mergedVisible || mounted"
    :class="`${prefixCls}-container`"
    @touchmove.stop.prevent
  >
    <aTransition
      v-if="mask"
      :duration="300"
      :show="mergedVisible"
      name="fade-drawer"
      appear
      :class="`${prefixCls}-mask`"
      @click="handleMask"
    >
    </aTransition>

    <aTransition
      :duration="300"
      :show="mergedVisible"
      appear
      :name="`slide-${placement}-drawer`"
      :class="drawerClass"
      :style="style"
      @after-leave="handleClose"
    >
      <div v-if="header" :class="`${prefixCls}-header`">
        <slot name="header">
          <div v-if="$slots.title || title" :class="`${prefixCls}-title`">
            <slot name="title">{{ title }}</slot>
          </div>
          <div
            v-if="closable"
            tabindex="-1"
            role="button"
            aria-label="Close"
            :class="[`${prefixCls}-close-btn`, 'arco-icon-hover']"
            @click="handleCancel"
          >
            <a-icon name="guanbi1"></a-icon>
          </div>
        </slot>
      </div>
      <div :class="`${prefixCls}-body`">
        <slot />
      </div>
    </aTransition>
  </div>
</template>

<script lang="ts">
import type { CSSProperties } from "vue";
import {
  computed,
  defineComponent,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
  toRefs,
  watch,
} from "vue";
import aTransition from "../arco-transition/index.vue";
import aIcon from "../arco-icon/index.vue";
// import { getPrefixCls } from "../_utils/global-config";
// import IconHover from "../_components/icon-hover.vue";
// import IconClose from "../icon/icon-close";
// import { useI18n } from "../locale";
// import { useOverflow } from "../_hooks/use-overflow";
// import { off, on } from "../_utils/dom";
// import usePopupManager from "../_hooks/use-popup-manager";
// import { isBoolean, isFunction, isNumber, isPromise } from "../_utils/is";
// import { KEYBOARD_KEY } from "../_utils/keyboard";
// import { useTeleportContainer } from "../_hooks/use-teleport-container";
import { props } from "./props";
import { isBoolean, isFunction, isNumber, isPromise } from "@/utils/is";
import useMergeState from "@/ArcoUni/hook/use-merge-state";

export default defineComponent({
  name: "Drawer",
  options: {
    // 虚拟化节点
    virtualHost: true,
  },
  components: {
    aIcon,
    aTransition,
  },
  props,
  emits: [
    "update:visible",
    "ok",
    "cancel",
    "open",
    "close",
    "beforeOpen",
    "beforeClose",
  ],
  setup(props, { emit }) {
    const prefixCls = "arco-drawer";

    const { visible, defaultVisible } = toRefs(props);

    const [mergedVisible, setVisible] = useMergeState(
      defaultVisible.value,
      reactive({ value: visible }),
    );
    const _okLoading = ref(false);
    const mergedOkLoading = computed(() => props.okLoading || _okLoading.value);

    const mounted = ref(mergedVisible.value);

    // let globalKeyDownListener = false;

    // const handleGlobalKeyDown = (ev: KeyboardEvent) => {
    //   if (props.escToClose && ev.key === KEYBOARD_KEY.ESC && isLastDialog()) {
    //     handleCancel(ev);
    //   }
    // };

    // const addGlobalKeyDownListener = () => {
    //   if (props.escToClose && !globalKeyDownListener) {
    //     globalKeyDownListener = true;
    //     on(document.documentElement, "keydown", handleGlobalKeyDown);
    //   }
    // };

    // const removeGlobalKeyDownListener = () => {
    //   if (globalKeyDownListener) {
    //     globalKeyDownListener = false;
    //     off(document.documentElement, "keydown", handleGlobalKeyDown);
    //   }
    // };

    // Used to ignore closed Promises
    let promiseNumber = 0;

    const close = () => {
      promiseNumber++;
      if (_okLoading.value) {
        _okLoading.value = false;
      }
      emit("update:visible", false);
      setVisible(false);
    };

    const handleOk = async (e: Event) => {
      const currentPromiseNumber = promiseNumber;
      const closed = await new Promise<boolean>(async (resolve) => {
        if (isFunction(props.onBeforeOk)) {
          let result = props.onBeforeOk((closed = true) => resolve(closed));
          if (isPromise(result) || !isBoolean(result)) {
            _okLoading.value = true;
          }
          if (isPromise(result)) {
            try {
              // if onBeforeOk is Promise<void> ,set Defaults true
              result = (await result) ?? true;
            } catch (error) {
              console.log(error, "我才是error");
              result = false;
            }
          }
          if (isBoolean(result)) {
            resolve(result);
          }
        } else {
          resolve(true);
        }
      });

      if (currentPromiseNumber === promiseNumber) {
        if (closed) {
          emit("ok", e);
          close();
        } else if (_okLoading.value) {
          _okLoading.value = false;
        }
      }
    };

    const handleCancel = (e: Event) => {
      let result = true;
      if (isFunction(props.onBeforeCancel)) {
        result = props.onBeforeCancel() ?? false;
      }
      if (result) {
        emit("cancel", e);
        close();
      }
    };

    const handleMask = (e: Event) => {
      if (props.maskClosable) {
        handleCancel(e);
      }
    };

    const handleOpen = () => {
      if (mergedVisible.value) {
        emit("open");
      }
    };

    const handleClose = () => {
      if (!mergedVisible.value) {
        mounted.value = false;
        // resetOverflow();
        emit("close");
      }
    };

    onMounted(() => {
      if (mergedVisible.value) {
        mounted.value = true;
        // setOverflowHidden();
        // addGlobalKeyDownListener();
      }
    });

    onBeforeUnmount(() => {
      //   resetOverflow();
      //   removeGlobalKeyDownListener();
    });

    watch(mergedVisible, (visible) => {
      if (mergedVisible.value !== visible) {
        setVisible(visible);
      }
      if (visible) {
        emit("beforeOpen");
        mounted.value = true;
        // setOverflowHidden();
        // addGlobalKeyDownListener();
      } else {
        emit("beforeClose");
        // removeGlobalKeyDownListener();
      }
    });

    const style = computed(() => {
      const style: CSSProperties = {
        [props.placement]: 0,
        ...(props.drawerStyle ?? {}),
      };
      if (["right", "left"].includes(props.placement)) {
        style.width = isNumber(props.width) ? `${props.width}px` : props.width;
        style.height = "100%";
      } else if (["center"].includes(props.placement)) {
        console.log("center");
        style["position"] = "relative";
      } else {
        style.minHeight = isNumber(props.height)
          ? `${props.height}px`
          : props.height;
      }
      return style;
    });

    const drawerClass = computed(() => [
      prefixCls,
      {
        [`${prefixCls}-${props.placement}`]: true,
      },
    ]);

    return {
      prefixCls,
      drawerClass,
      style,
      mounted,
      mergedVisible,
      mergedOkLoading,
      handleOk,
      handleCancel,
      handleOpen,
      handleClose,
      handleMask,
    };
  },
});
</script>
